package com.open.free.boot.web.controller;

import com.open.free.boot.common.constant.Constants;
import com.open.free.boot.common.jwt.JWTUtils;
import com.open.free.boot.common.lang.JsonUtils;
import com.open.free.boot.common.lang.StringToolUtils;
import com.open.free.boot.common.redis.JRedisUtils;
import com.open.free.boot.core.annotation.JwtIgnore;
import com.open.free.boot.core.controller.BaseController;
import com.open.free.boot.core.entity.SmsEntity;
import com.open.free.boot.core.result.ResultData;
import com.open.free.boot.core.result.ResultEnum;
import com.open.free.boot.web.model.UserInfoModel;
import com.open.free.boot.web.requestQuery.UserRequest;
import com.open.free.boot.web.service.MenuService;
import com.open.free.boot.web.service.UserInfoService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Faye.Wang
 * @version 1.0
 * @date 2020/9/5 11:36
 * @Description 用户信息表操作
 */
@RestController
@RequestMapping("/api")
public class UserController extends BaseController {
    @Value("${pass.salt}")
    private String salt;
    @Value("${jwt.expire.time}")
    private long expireTime;
    @Value("${jwt.access.token.secret}")
    private String jwtSecret;
    @Value("${user.login.redis.time}")
    private Integer loginExpireTime;
    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private MenuService menuService;

    /**
     * 获取手机验证码
     * @param smsEntity
     * @return
     * @Description 判断短信发送此处，累加+1大于五次后，无法在进行短信发送，需要等待30分钟再可进行继续发送
     */
    @PostMapping("/sendSms")
    @JwtIgnore
    public ResultData getSmsCold(@RequestBody SmsEntity smsEntity){
        String msgCode = StringToolUtils.generatorRollNum();
        //TODO
        System.out.println("短信code-----------:"+msgCode);

        if(StringUtils.isBlank(JRedisUtils.getKeyValue(Constants.USER_SEND_REDIS_KEY+ smsEntity.getPhone()))){
            JRedisUtils.setKeyValue(Constants.USER_SEND_REDIS_EXPIRE+smsEntity.getPhone(),"1",Constants.MSG_COUNT_CODE_TIME);
        }else{
            String sendCount = JRedisUtils.getKeyValue(Constants.USER_SEND_REDIS_EXPIRE+smsEntity.getPhone());
            // 短信发送此处大于5次，30分钟内禁止发送短信
            if(Integer.parseInt(sendCount) >= Constants.NOT_ALLOW_SEND_MSG){
                return new ResultData(ResultEnum.HTTP_SMS_FAIL_201);
            }
            BigDecimal num1 = new BigDecimal(sendCount).add(new BigDecimal("1"));
            JRedisUtils.setKeyValue(Constants.USER_SEND_REDIS_EXPIRE+smsEntity.getPhone(),num1.toString(),Constants.MSG_COUNT_CODE_TIME);
        }
        JRedisUtils.setKeyValue(Constants.USER_SEND_REDIS_KEY+ smsEntity.getPhone(),msgCode, Constants.MSG_CODE_TIME);
        return super.resultSuccess();
    }


    /**
     * 用户注册
     * @param user
     * @param code
     * @return
     * @Description 判断验证码是否整，验证用户名是否已经被注册
     */
    @PostMapping("/userSignUp")
    @JwtIgnore
    public ResultData userSignUp(@RequestBody UserInfoModel user,@RequestParam String code){
        String smsCode = JRedisUtils.getKeyValue(Constants.USER_SEND_REDIS_KEY+ user.getUserMobile());
        // 判断验证码是否相等 or 验证为NULL 即 验证码超时
        if(StringUtils.isBlank(smsCode) || !StringUtils.equals(code,smsCode)){
            return super.resultFail(ResultEnum.HTTP_SMS_CODE_ERROR_202);
        }
        // 判断用户名是否已注册
        List<UserInfoModel> userInfoModels = userInfoService.getUserHasSignUp(user.getUserName());
        if(userInfoModels.isEmpty()){
            return super.resultFail(ResultEnum.HTTP_MSG_CODE_ERROR_203);
        }
        String passWord = StringToolUtils.digestPassword(user.getUserPass(),salt);
        user.setUserPass(passWord);
        userInfoService.insertUserInfo(user);
        return super.resultSuccess();
    }

    /**
     * 找回密码
     * @param user
     * @param code
     * @return
     */
    @PostMapping("/userForgetPass")
    @JwtIgnore
    public ResultData userForgetPass(@RequestBody UserInfoModel user,@RequestParam String code){
        String smsCode = JRedisUtils.getKeyValue(Constants.USER_SEND_REDIS_KEY+ user.getUserMobile());
        // 判断验证码是否相等 or 验证为NULL 即 验证码超时
        if(StringUtils.isBlank(smsCode) || !StringUtils.equals(code,smsCode)){
            return super.resultFail(ResultEnum.HTTP_SMS_CODE_ERROR_202);
        }
        String passWord = StringToolUtils.digestPassword(user.getUserPass(),salt);
        user.setUserPass(passWord);
        userInfoService.updateUserPassWord(user);
        return super.resultSuccess();
    }

    /**
     * 用户双因子登录
     * @param userRequest
     * @return
     */
    @PostMapping("/userSignIn")
    @JwtIgnore
    public ResultData userSignIn(@RequestBody UserRequest userRequest){

        if(userRequest.getType()!=Constants.USER_LOGIN_TYPE){
            String smsCode = JRedisUtils.getKeyValue(Constants.USER_SEND_REDIS_KEY+ userRequest.getUserMobile());
            // 判断验证码是否相等 or 验证为NULL 即 验证码超时
            if(StringUtils.isBlank(smsCode) || !StringUtils.equals(userRequest.getCode(),smsCode)){
                return super.resultFail(ResultEnum.HTTP_SMS_CODE_ERROR_202);
            }
        }
        String passWord = StringToolUtils.digestPassword(userRequest.getPassWord(),salt);
        String userName = userRequest.getUserName();
        // 判断用户密码是否正确
        List<UserInfoModel> userInfoModels = userInfoService.getUserSignIn(userName,passWord);
        if(userInfoModels.isEmpty()){
            return super.resultFail(ResultEnum.HTTP_MSG_CODE_ERROR_204);
        }
        UserInfoModel user = userInfoModels.get(0);
        // 前端sessionId，用户后端获取用户信息
        String sessionId = StringToolUtils.getGeneratorUUID();
        Map<String,String> tokenMap = new HashMap<>();
        tokenMap.put("userName",userName);
        tokenMap.put("sessionId",sessionId);
        tokenMap.put("userId",String.valueOf(user.getId()));

        JRedisUtils.setKeyValue(Constants.USER_OAUTH_SESSION_ID+sessionId, JsonUtils.toJsonString(tokenMap),loginExpireTime);

        // 生成业务请求Token
        String accessToken = JWTUtils.createSingleJwtToken(tokenMap,expireTime,jwtSecret);


        List<Object> menuList = menuService.getSysmenuModelList();

        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("sessionId",sessionId);
        resultMap.put("token",accessToken);
        resultMap.put("userName",userName);
        resultMap.put("email",user.getUserEmail());
        //TODO 用户头像
        resultMap.put("avatar","./assets/tmp/img/avatar.jpg");
        Map<String,Object> userMap = new HashMap<>();
        userMap.put("user",resultMap);
        userMap.put("menu",menuList);
        System.out.println(JsonUtils.toJsonString(menuList));
        return super.resultSuccess(userMap);
    }

}
